/*
// Do we need to allocate the Vault?
Type.registerNamespace('Vault');

// provides support for the Vault rating features.
Vault.RatingSupport = function()
{
    this._items = [];
};

Vault.RatingSupport.prototype =
{
    init : function(index, ratingValue, assetId)
    {
        if (this._items[index]) {
            return;
        }

        var rating = new Rating('RatingBar', index);
        rating.emptyStarCssClass = 'emptyRatingStar';
        rating.filledStarCssClass = 'filledRatingStar';
        rating.starCssClass = 'ratingStar';
        rating.waitingStarCssClass = 'savedRatingStar';
        rating.initialize(ratingValue, assetId, this.rateAsset);
        this._items[index] = true;
    },

    rateAsset : function(ratingValue, rollbackValue, ratingObj) {
        var assetId = ratingObj.target;

        // Call Web Service.
        VaultServices.RateAsset( assetId, ratingValue,
            function() {
                // Success
                ratingObj.onSuccess(ratingValue);
            },
            function(error) {
                // Fail
                var errorMsg = 'Failed to connect to server: ' + error.get_message();
                ratingObj.onFail(error, errorMsg, rollbackValue);
            }
        );
    },

    test : function(ratingValue, assetId) {
        alert('id='+assetId+'\nrating='+ratingValue);
    },

    ajax : function(url) {
        alert(url);
        var ajax = new Ajax.Request(url, { // [prototype.js]
            method:'get',
            onSuccess: function(transport) {
                alert('Success! \n\n' + value);
            },
            onFailure: function() {
                alert('Something went wrong...');
            }
        });
    }
};

$vaultRating = new Vault.RatingSupport();
*/

/**
 * Display debug message.
 * @param {String} msg
 */
function show(msg)
{
    $('status').innerHTML = msg; // [prototype.js]
}

/**
 * An event-specific variant of bind which makes sure the function will recieve
 * the current event object as the first argument when executing.
 * @param {Object} obj The object to bind the event handler.
 * @param {Function} handler The event handler.
 * @return {Function} The new binding event handler.
 */
function createDelegate(obj, handler) {
    //show(handler); // debug
    return handler.bindAsEventListener(obj); // [prototype.js]
}

/**
 * Constructor for Rating class.
 * @param {String} name The name of Rating control.
 * @param {int} index The index of Rating control.
 */
Rating = function(name, index) {
    this.name = name;
    this.index = index;
    this.target = null;

    this.starCssClass = null;
    this.filledStarCssClass = null;
    this.emptyStarCssClass = null;
    this.waitingStarCssClass = null;

    this._ratingValue = 0;
    this._currentRating = 0;
    this._maxRatingValue = 5;
    this._stars = null;
    this._mouseOutHandler = createDelegate(this, this._onMouseOut);
    this._starClickHandler = createDelegate(this, this._onStarClick);
    this._starMouseOverHandler = createDelegate(this, this._onStarMouseOver);
    this._keyDownHandler = createDelegate(this, this._onKeyDownBack);
    this._ratedHandler = null;
};

/**
 * Rating methods.
 */
Rating.prototype = {
    initialize : function(initRating, target, handler) {
        if (Object.isNumber(initRating)) { // [prototype.js]
            if (initRating > 0 && initRating <= this._maxRatingValue) {
                this._ratingValue = initRating;
                this._currentRating = initRating;
            }
        }

        this.target = target;

        if (Object.isFunction(handler)) { // [prototype.js]
            this._ratedHandler = handler;
        }

        // Bind star events.
        var eltName = this.name + this.index;
        var elt = $(eltName); // [prototype.js]
        this._stars = [];
        for (var i = 1; i <= this._maxRatingValue; i++) {
            var starName = eltName + '_Star_' + i;
            var starElement = $(starName); // [prototype.js]
            starElement.value = i;
            this._stars.push(starElement);
            starElement.observe('click', this._starClickHandler); // [prototype.js]
            starElement.observe('mouseover', this._starMouseOverHandler); // [prototype.js]
        }
        elt.observe('mouseout', this._mouseOutHandler); // [prototype.js]
        elt.observe('keydown', this._keyDownHandler); // [prototype.js]

        this._update();
    },

    dispose : function() {
        var eltName = this.name + this.index;
        var elt = $(eltName); // [prototype.js]
        if (this._stars != null) {
            for (var i = 0; i < this._stars.length; i++) {
                var starElement = this._stars[i];
                starElement.stopObserving('click', this._starClickHandler); // [prototype.js]
                starElement.stopObserving('mouseover', this._starMouseOverHandler); // [prototype.js]
            }
            this._stars = null;
        }
        elt.stopObserving('mouseout', this._mouseOutHandler); // [prototype.js]
        elt.stopObserving('keydown', this._keyDownHandler); // [prototype.js]
    },

    get_Rating : function() {
        return this._ratingValue;
    },

    set_Rating : function(value) {
        if (this._ratingValue != value) {
            if ((value < 0) || (value > this._maxRatingValue)) {
                return;
            }

            this._currentRating = value;
            this._ratingValue = value;
            this._update();
        }
    },

    onSuccess : function(ratingValue) {
        var str = (ratingValue == 1) ? 'star' : 'stars';
        //alert('You rated '+ ratingValue + ' ' + str + ' to the asset!');
        this.set_Rating(ratingValue);
    },

    onFail : function(error, errorMsg, rollbackValue) {
        if (errorMsg) {
            alert(errorMsg);
        } else {
            alert(error.get_message());
        }

        this.set_Rating(rollbackValue);
    },

    _onMouseOut : function(e) {
        this._currentRating = this._ratingValue;
        this._update();
    },

    _onStarClick : function(e) {
        if (this._ratingValue != this._currentRating) {
            this._onRating(this._currentRating);
        }
    },

    _onStarMouseOver : function(e) {
        var star = e.element();
        this._currentRating = star.value;
        this._update();
    },

    _onKeyDownBack : function(ev) {
        // TODO
    },

    _onRating: function(value) {
        var rollbackValue = this._ratingValue;
        this.set_Rating(value);

        if (Object.isFunction(this._ratedHandler)) { // [prototype.js]
            this._ratedHandler(value, rollbackValue, this);
        }
    },

    _update : function() {
        var eltName = this.name + this.index;
        var elt = $(eltName); // [prototype.js]
        elt.title = this._currentRating;
        //show(this._currentRating); // debug

        for (var i = 0; i < this._maxRatingValue; i++) {
            var starElement;
            starElement = this._stars[i];

            if (this._currentRating > i) {
                starElement.removeClassName(this.emptyStarCssClass); // [prototype.js]
                starElement.addClassName(this.filledStarCssClass); // [prototype.js]
            }
            else {
                starElement.removeClassName(this.filledStarCssClass); // [prototype.js]
                starElement.addClassName(this.emptyStarCssClass); // [prototype.js]
            }
        }
    }
}